package main

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"os"
	"strconv"
	"strings"
)

// 先发送消息长度
func Write(conn net.Conn, txt string) error {
	length := len(txt)
	_, err := conn.Write([]byte(fmt.Sprintf("%05d", length)))
	if err != nil {
		return err
	}
	_, err = conn.Write([]byte(txt))
	if err != nil {
		return err
	}
	return nil
}

// 通过消息长度创建字节切片接收消息
func Read(conn net.Conn) (string, error) {
	lengthBytes := make([]byte, 5)
	_, err := conn.Read(lengthBytes)
	if err != nil {
		return "", err
	}
	length, _ := strconv.Atoi(string(lengthBytes))
	ctx := make([]byte, length)
	n, err := conn.Read(ctx)
	if err != nil {
		return "", err
	}
	return string(ctx[:n]), nil
}
func Input(prompt string) string {
	fmt.Println(prompt)
	scaner := bufio.NewScanner(os.Stdin)
	scaner.Scan()
	return strings.TrimSpace(scaner.Text())
}

func main() {
	// addr := net.JoinHostPort("127.0.0.1", "8080")
	addr := "127.0.0.1:8080"
	// 如果需要在机器外部访问需要使用 外部可以访问的网卡ip
	// 多网卡 0.0.0.0:8888  :8888

	protocol := "tcp"

	// 1.监听服务
	listener, err := net.Listen(protocol, addr)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("listener addr", listener.Addr())

	// 2.接收客户端请求
	for {
		conn, err := listener.Accept()

		if err != nil {
			fmt.Println(err)
			return
		} else {
			fmt.Printf("客户端[%s]连接成功！", conn.RemoteAddr())
			for {
				fmt.Println("客户端发送：")
				txt, err := Read(conn)
				if err != nil {
					if err != io.EOF {
						fmt.Println(err)
					}
					break
				}
				fmt.Println(txt)

				txt = Input("请输入信息：")
				if txt == "exit" {
					break
				}
				err = Write(conn, txt)
				if err != nil {
					if err != io.EOF {
						fmt.Println(err)
					}
					break
				}
			}
			// remotetxt := Read(conn)
			// if remotetxt == "quit" {
			// 	break
			// }
			// fmt.Println(remotetxt)

			// // 打印本地ip+端口与对端ip+端口
			// fmt.Println(conn.LocalAddr(), conn.RemoteAddr())
			// // 3.与客户端交换数据
			// fmt.Println(Read(conn))
			// // 4.关闭客户端
			conn.Close()

		}

	}

	// 5.关闭服务
	listener.Close()
}
